package org.raymond.iworks.study.app;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.raymond.iworks.apis.vo.permission.PermissionNodeVO;
import org.raymond.iworks.repository.entity.TSysPermission;
import org.raymond.iworks.repository.repository.TSysPermissionRepository;
import org.raymond.iworks.StudyApplication;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.stream.Collectors;

@SpringBootTest(classes= StudyApplication.class)
@Slf4j
public class PermissionTest {
    @Autowired
    private TSysPermissionRepository tSysPermissionRepository;

    @Test
    public void testTree(){
        List<TSysPermission> list = tSysPermissionRepository.findAll();
        List<TSysPermission> cloneList = list.stream().collect(Collectors.toList());

        long start = System.currentTimeMillis();
        PermissionNodeVO top = null;
        for(int i=0; i<1; i++) {
            top = walkTree(cloneList);
        }
        long middle = System.currentTimeMillis();
        log.info("top:{}, post:{} ms", JSONUtil.toJsonStr(top), (middle-start));

        cloneList = list.stream().collect(Collectors.toList());
        middle = System.currentTimeMillis();
        for(int i=0; i<1000; i++) {
            walkTree(cloneList);
        }
        long end = System.currentTimeMillis();
        log.info("post:{} ms", (end-middle));
    }

    private PermissionNodeVO walkTree(List<TSysPermission> list){
        PermissionNodeVO top = new PermissionNodeVO();
        top.setId(0L);
        List<PermissionNodeVO> all = list.stream().map(e -> {
            PermissionNodeVO node = new PermissionNodeVO();
            BeanUtils.copyProperties(e, node);
            return node;
        }).collect(Collectors.toList());

        List<PermissionNodeVO> firstNodes = child(0L, all);
        top.setChildren(firstNodes);
        return top;
    }

    private List<PermissionNodeVO> child(Long parentId, List<PermissionNodeVO> all){
        List<PermissionNodeVO> children = all.stream().filter(e->e.getParentId().equals(parentId)).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(children)) {
            children.stream().forEach(c -> {
                List<PermissionNodeVO> childChildRen = child(c.getId(), all);
                c.setChildren(childChildRen);
            });
            all.removeAll(children);
        }
        return children;
    }
}
